﻿/* Class Supported Code */

/*
 * Function: Class
 * Purpose:  javascript oo-programming
 * Returns:  a new class object
 * Inputs:   class members
 */
var Class = function(subclass) {
    subclass.setOptions = function(options) {
        this.options = jQuery.extend({}, this.options, options);
        for (var key in options) {
            if (/^on[A-Z][A-Za-z]*$/.test(key)) {
                $(this).bind(key, options[key]);
            }
        }
    }
    var fn = function() {
        if (subclass._init && typeof subclass._init == 'function') {
            this._init.apply(this, arguments);
        }
    }
    if (typeof subclass == 'object') {
        fn.prototype = subclass;
    }
    return fn;
}

// NameSpace Register
var Namespace = {
    Register: function (_Name) {
        var chk = false;
        var cob = "";
        var spc = _Name.split(".");
        for (var i = 0; i < spc.length; i++) {
            if (cob != "") { cob += "."; }
            cob += spc[i];
            chk = this.Exists(cob);
            if (!chk) { this.Create(cob); }
        }
        if (chk) { throw "Namespace: " + _Name + " is already defined."; }
    },

    Create: function (_Src) {
        eval("window." + _Src + " = new Object();");
    },

    Exists: function (_Src) {
        eval("var NE = false; try{if(" + _Src + "){NE = true;}else{NE = false;}}catch(err){NE=false;}");
        return NE;
    }
}

/* example:
var ClassName =  new Class({
	options:{
		containerId: null,
		auto: true

	},
	
	_init:function(options){
		this.setOptions(options);
		this.containerId = this.options.containerId;
        this.auto = this.options.containerId;
	}
});
*/


var DetailTable = new Class({
    options: {
        sTableId: null,
        sAjaxsource: null,
        sDetailAjaxsource: null,
        aoColumns: [],
        oExtraOpts: {}
    },
    _fnRowDetailRequest: function(container, para) {
        $.ajax({
            "url": this.options.sDetailAjaxsource,
            "data": { "pkid": para },
            "type": "post",
            "success": function(detail) {
                container.html(detail);
            },
            "dataType": "html",
            "cache": false
        });
    },
    _fnCloseAccordion: function(trNode) {
        trNode.removeClass("accordion-open");
        trNode.next().remove();
    },
    _fnOpenAccordion: function(trNode) {
        var detail = $("<tr class='accordion'><td colspan='" + trNode.children().length + "'>Loading...</td></tr>");
        trNode.addClass("accordion-open");
        detail.insertAfter(trNode);
        this._fnRowDetailRequest(detail.children("td"), trNode.data("PKID"));
    },
    _fnIconClick: function(event) {
        var trNode = $(event.currentTarget).parent();
        if (trNode.hasClass("accordion-open")) {
            this._fnCloseAccordion(trNode);
        } else {
            this._fnOpenAccordion(trNode);
        }
    },
    _fnRowClickCallBack: function(event) {
        var trNode = $(event.currentTarget);
        if (trNode.hasClass("accordion-open")) {
            this._fnCloseAccordion(trNode);
        } else {
            this._fnOpenAccordion(trNode);
        }
    },
    _fnIconClick: function(event) {
        var trNode = $(event.currentTarget).parent();
        if (trNode.hasClass("accordion-open")) {
            this._fnCloseAccordion(trNode);
        } else {
            this._fnOpenAccordion(trNode);
        }
    },
    _fnRowCallBack: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
        $(nRow).data("PKID", aData[0]);
        $(nRow).dblclick(this._fnRowClickCallBack.binding(this));
        var icon = $("<td class='icon'></td>");
        icon.insertBefore($(nRow).children()[0]);
        icon.click(this._fnIconClick.binding(this));
        return nRow;
    },

    _init: function(options) {
        this.setOptions(options);
        $('#' + this.options.sTableId).dataTable({
            "sDom": '<"toolbar">frtip',
            "sPaginationType": "full_numbers",
            "bProcessing": true,
            "bSortClasses": false,  // when we add a extra column on the left hand of table, we must disable the sortclass feature which will destory the background img of icon.
            "bServerSide": true,
            "bLengthChange": false,
            "bAutoWidth": false,    // we donot need fixed with for our table
            "fnRowCallback": this._fnRowCallBack.binding(this),     // we must use this to make sure we can use member function in the callback fucntion
            "fnServerData": function(sSource, aoData, fnCallback) {
                var sData = JSON.stringify(aoData);
                $.ajax({
                    "url": sSource,
                    "data": sData,
                    "type": "post",
                    "success": fnCallback,
                    "contentType": "application/json",
                    "dataType": "json",
                    "cache": false,
                    "error": function(xhr, error, thrown) {
                        if (error == "parsererror") {
                            alert("DataTables warning: JSON data from server could not be parsed. " +
								    "This is caused by a JSON formatting error.");
                        }
                    }
                });
            },
            "aoColumns": this.options.aoColumns,
            "sAjaxSource": this.options.sAjaxsource
        });

        $("<td class='icon'></td>").insertBefore($('#' + this.options.sTableId + ' thead tr').children()[0]);
    }
});

// Global Function
function guidGenerator() {
    var S4 = function () {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    };
    return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
}

function idGenerator() {
    var S4 = function () {
        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
    };
    return (S4() + S4() + "-" + S4());
}

// implement JSON.stringify serialization  
JSON.stringify = JSON.stringify || function(obj) {
    var t = typeof (obj);
    if (t != "object" || obj === null) {
        // simple data type  
        if (t == "string") obj = '"' + obj + '"';
        return String(obj);
    }
    else {
        // recurse array or object  
        var n, v, json = [], arr = (obj && obj.constructor == Array);
        for (n in obj) {
            v = obj[n]; t = typeof (v);
            if (t == "string") v = '"' + v + '"';
            else if (t == "object" && v !== null) v = JSON.stringify(v);
            json.push((arr ? "" : '"' + n + '":') + String(v));
        }
        return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
    }
};


function hide(id) {
    $('#' + id).css('display', 'none');
}

function show(id) {
    $('#' + id).css('display', 'block');
}


function showOrhide(id, self) {
    var $ele = $('#' + id)
    var $that = $(self);
    var display = $ele.css('display');

    if (display != 'none') {
        $ele.css('display', 'none');
        $that.removeClass('ag-open').addClass('ag-close');
    } else {
        $ele.css('display', 'block');
        $that.removeClass('ag-close').addClass('ag-open');
    }
}

function InitAutocomplete() {
    $("input[auto-value=true]").each(function (index, Element) {
        $ele = $(Element);
        $ele.autocomplete($ele.attr("auto-service"),{minChars: 0,zaltaWidth: 24, cacheLength: 0});
    });
}

// Custom function
function InitDropdown(aoDropdownable) {
    while (aoDropdownable.length != 0) {
        var dropdown = aoDropdownable.pop();
        NIRA.Dropdown.Standard(dropdown);
    }
}

function begetObject(o) {
    function F() { }
    F.prototype = o;
    return new F();
}

// Namespace `NIRA.Dropdown`
Namespace.Register('NIRA.Dropdown');
Namespace.Register('NIRA.Dropdown.Standard');
NIRA.Dropdown = function () {
    var instances = [];
    var activeInst = null;
	// Notes: when click the normal space, the dropdown isntance will hide.
    jQuery(document.body).click(function () {
        HideActive();
    })
	/*
	 * Function: HideActive
	 * Purpose:  hide the active dropdown object
	 * Returns:  none
	 * Inputs:   none
	 */
    function HideActive() {
        if (!!activeInst) {
            activeInst.hideInst();
        }
    }

	/*
	 * Function: SetPostion
	 * Purpose:  set the position of dropdown content
	 * Inputs:   $:container - container bar
	 *			 $:content - the content to drop down
	 *			 bool:bleft - If true, stay left, else stay right
	 */
    function SetPostion(container, content, bleft) {
        if (bleft == undefined) bleft = false;
        var offset = container.offset();
        var left = bleft ? offset.left : offset.left + container.width() - content.width() - 2;
        var top = offset.top + container.height();
        content.css({ left: left, top: top });
    }
	
	/*
	 * Function: BindTrigger
	 * Purpose:  bind click event to trigger
	 * Inputs:   object:dropdown unit - the dropdown unit need to bind trigger
	 */
	function BindTrigger(unit) {
		unit.trigger.click(function (e) {
			e.preventDefault();
            e.stopPropagation();
            if (activeInst === unit) {
                unit.hideInst();
                return;
            }

            HideActive();
            unit.displayInst();
        });
	}
	/*
	 * Function: IsElementId
	 * Purpose:  Whether a string is element id or url
	 * Inputs:   string:target - element id(include #) or url string
	 * return:	 If target string is a element id, return true, else return false.
	 */
	function IsElementId(target) {
		return target.indexOf('#') === 0;
	}
	
	/*
	 * Function: InitTarget
	 * Purpose:  initialize a target
	 * Inputs:   jquery: target - jquery element need to be 
	 */
	 

    return {
		/*
		 * Function: initInstance
		 * Purpose:  Init a dropdown instance object
		 * Inputs:   string:trigger - trigger element id
		 *			 string:container - container element id
		 *			 string:target - ajax url or element id
		 *			 bool:left - position option
		 */
        initInstance: function (trigger, container, target, left) {
            var that = this;
            this.trigger = $(trigger), this.container = $(container), this.target = target, this.left = left == true;
			
			if(IsElementId(target)) {
				this.target = $(target);
				this.target.click(function (e) { e.stopPropagation();});
				this.target.css('display', 'none');
			}
			
			BindTrigger(that);
        },
		/*
		 * Function: displayTarget
		 * Purpose:  display target and mark self as active
		 */
        displayTarget: function () {
            this.target.css('display', 'block');
            SetPostion(this.container, this.target, this.left);
            activeInst = this;
        },
		/*
		 * Function: displayInst
		 * Purpose:  Initial loading targer, Close current active instance and diaplay self target.
		 * Inputs:   none
		 * Notes:	 In ajax case, if it is first loading, if will request the target content first.
		 */
        displayInst: function () {
            var that = this;
            if (typeof this.target == 'string') {
                // get content from ajax
                $.ajax({
                    "url": that.target,
                    "type": "post",
                    "success": function (content) {
                        var $content = $(content).appendTo($("body"));
                        $content.click(function (e) { e.stopPropagation();});
                        $content.css({ display: "block", left: -500, top: -500, width: $content.width() > 200 ? $content.width() : 200 });
                        that.target = $content;
                        that.displayTarget();
                    },
                    "dataType": "html",
                    "cache": false
                });
                return;
            }

            that.displayTarget();
        },
		/*
		 * Function: hideInst
		 * Purpose:  If this is active instance, close this and mark active flag to null
		 */
        hideInst: function () {
            this.target.css('display', 'none');
            activeInst = null;
        },
		/*
		 * Function: addInstance
		 * Purpose:  initialize a dropdown isntance and push it to stack
		 * Inputs:   object:inst - dropdown settings object
		 */
        addInstance: function (inst) {
            var that = this;
            that.displayed = false;
            if (inst.target == undefined) inst.target = $(inst.trigger).attr('href');
            that.initInstance(inst.trigger, inst.container, inst.target, inst.left);
            instances.push(that);
        },
		/*
		 * Function: getInstanceCount
		 * Purpose:  get registered instance count
		 * Inputs:   none
		 * return:	 int:gegistered instance count
		 */
		getInstanceCount: function() {
			return instances.length;
		},
		
		/*
		 * Function: getActiveInst
		 * Purpose:  get active drop down instance
		 * Inputs:   none
		 * return:	 object: dropdown unit
		 */
		getActiveInst: function() {
			return activeInst;
		}
    }
} ();
/*
 * Function: NIRA.Dropdown.Standard
 * Purpose:  add a new dropdown instance
 * Returns:  dropdown instance
 * Inputs:   object:inst - dropdown settings object
 */
NIRA.Dropdown.Standard = function (oSettings) {
    var that = begetObject(NIRA.Dropdown);
    that.addInstance(oSettings);
    return that;
};



(function ($) {
    // overlay class initial living
    $(".dont-default-focus").live("focusin", function () {
        var label = $(this).children(".overlabel")[0];
        $(label).css("display", "none");
    });

    $(".dont-default-focus").live("focusout", function () {
        var input = $(this).children(".overinput")[0];
        var label = $(this).children(".overlabel")[0];
        if (input.value == "") $(label).css("display", "block");
    });

    $(".drop-content").live("mouseenter", function () {
        $(this).prev().find(".drop-lnk").data("hoverd", "true");
    });

    $(".drop-content").live("mouseleave", function () {
        $(this).prev().find(".drop-lnk").data("hoverd", "false");
    });

    $(".drop-lnk").live("click", function (event) {
        event.preventDefault();
        var status = $(this).data("status");
        if (status == undefined || status == "close") {
            $(this).data("status", "open");
            $(this).parent().next().css("display", "block");
        } else {
            $(this).data("status", "close");
            $(this).parent().next().css("display", "none");
        }
    });

    $(".drop-lnk-ajax").live("click", function (event) {
        event.preventDefault();
        var that = $(this);
        $.ajax({
            "url": $(this).attr("href"),
            "type": "post",
            "success": function (submenu) {
                var ele = that.parent();
                $(submenu).insertAfter(that.parent());
                that.removeClass("drop-lnk-ajax").addClass("drop-lnk");
                that.click();
            },
            "dataType": "html",
            "cache": false
        });
    });

    $(".drop-lnk").live("focusout", function () {
        var hovered = $(this).data("hoverd");
        if (hovered == undefined || hovered == "false") {
            $(this).data("status", "close");
            $(this).parent().next().css("display", "none");
        }
    });

    $(".ajax-update-lnk").live("click", function (event) {
        event.preventDefault();
        var that = $(this);
        $.ajax({
            "url": $(that).attr("href"),
            "type": "post",
            "success": function (tab) {
                var container = $("#" + $(that).attr("rel"));
                container.html(tab);
                that.parent().parent().find(".active").removeClass("active");
                that.parent().addClass("active");
            },
            "dataType": "html",
            "cache": false
        });
    });
    InitAutocomplete();
} (jQuery));